/**
 * This file is part of the CAKIS project.
 * 
 * Copyright (c) 2009-2010 - Florian Arndt, Christian Kerl
 * 
 * @license GNU Lesser General Public License v3 <http://www.opensource.org/licenses/lgpl-3.0.html>
 * @since   01.03.2010
 * @version SVN: $Id: ProductLookupServiceRegistryImpl.java 130 2010-05-13 22:11:13Z christian-kerl@web.de $
 */

package org.cakis.server.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.cakis.server.Names;
import org.cakis.server.model.Product;
import org.cakis.server.service.ProductLookupService;
import org.cakis.server.service.ProductLookupServiceRegistry;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.log.Log;

/**
 * Implementation of {@link ProductLookupServiceRegistry}.
 * 
 * @author Christian Kerl
 */
@Name(Names.ProductLookupServiceRegistry)
@Scope(ScopeType.APPLICATION)
@Startup
public class ProductLookupServiceRegistryImpl implements ProductLookupServiceRegistry {
    /**
     * Basic {@link ProductLookupService} implementation, which registers itself with a
     * {@link ProductLookupServiceRegistryImpl} instance on creation.
     * 
     * @author Christian Kerl
     */
    public static abstract class SelfRegisteringProductLookupService implements ProductLookupService {
        @In(value = Names.ProductLookupServiceRegistry, required = true, create = true)
        private ProductLookupServiceRegistry registry;

        @Create
        public void register() {
            if(registry != null) {
                registry.addService(this);
            }
        }

        @Destroy
        public void unregister() {
            if(registry != null) {
                registry.removeService(this);
            }
        }
    }

    @Logger
    private Log log;

    private final Map<String, ProductLookupService> services = new HashMap<String, ProductLookupService>();

    @Override
    public List<ProductLookupService> getServices() {
        return new ArrayList<ProductLookupService>(services.values());
    }

    @Override
    public ProductLookupService getServiceByName(String name) {
        return services.get(name);
    }

    @Override
    public void addService(ProductLookupService service) {
        services.put(service.getName(), service);

        log.info("Added ProductLookupService #0.", service.getName());
    }

    @Override
    public void removeService(ProductLookupService service) {
        services.remove(service);

        log.info("Removed ProductLookupService #0.", service.getName());
    }

    @Override
    public Product getProductInformation(String ean) {
        log.info("Search Product with EAN #0.", ean);

        Product result = null;

        for(ProductLookupService service : services.values()) {
            result = service.getProductInformation(ean);

            if(result != null) {
                log.info("Found Product with EAN #0 at #1.", ean, service.getName());

                break;
            }
        }

        return result;
    }
}
